//styl KNF BSD moj ulubiony i obowiazujacy w tym w przypadku C++
//ogolnie preferuje bardzo zbity kod, niektorzy twierdza ze jest niezbyt czytelny ale nimi bym sie nie przejmowal
//jako wciec w kodzie uzywamy czterech spacji
//wykorzystujemy linuksowe konce linii

class Base { //nawiasy klamrowe zawsze w tej samej linii
    //jesli to mozliwe pomijamy slowo kluczowe private
    int i;
    double j;
    public: //po modyfikatorze dostepu wciecie
        //metody definiujemy / deklarujemy jedna pod druga bez linii odstepu
        //Zawsze pierwsze ida konstruktory
        Base() : i(0), j(0.0) {} //po otwarciu nawiasu nie ma spacji, jesli to mozliwe inlinujemy metode
        //unikamy przykrywania zmiennych
        //Base(int i, double j) : i(i), j(j) {} -> dziala, ale jest srednio czytelne
        Base(int ii, double jj) : i(ii), j(jj) {}
        Base(const Base& lhs) : i(lhs.i), j(lhs.j);
        //Po konstruktrach zamieszczamy destruktor
        virtual ~Base() {}
        //Po deskruktorze zamieszczamy operator przypisana (jesli istnieje), kolejnosc pozostalych operatorow jest dowolna
        Base& operator=(const Base&);
        //Jesli nie musimy podawac nazwy argumentu, to jej nie podajemy
        virtual void dummy1(int);
        bool dummy2() {
            if(1 == i) { //stale zawsze po lewej stronie
                /.../
            } else { //else w tej samej linii
                /.../
            }
            if(2.0 == 0) return true; //jesli to mozliwe to nie otwieramy nawiasow klamrowych
            else return false;
        }
};

class Derived : public Base { //podczas dziedziczenia jawnie zmaieszczamy poziom dziedziczenia (nwet w przypadku private)
    
};

//w templatach zawsze uzywamy typename zamiast class
template<Iter T>
class Wrapper {
    //tam gdzie to mozliwe uzywamy typedef
    //jednoczesnie jesli to mozliwe enkapsulujemy typedefy, dlatego zamieszczamy je w sekcji private
    typedef typename Iter::value_type value_type;
};

int main() {
    //przykladowe iteracje
    int a = 3;
    vector<int> vi;
    for(int i = 0; i < a; ++i) vi.push_back(i); //wykorzystujemy preinkrementacje
    //jesli iterujemy po konktenerze, wykorzystujemy iteratory (stale jesli to mozliwe), koncowy iterator tworzymy przed wejsciem do petli
    typedef typename vector<int>::const_iterator ci;
    ci end = vi.end();
    for(ci first = vi.begin(); first != end; ++first) cout << *first << endl;
    return 0; //metoda main ma zawsze zwracac wartosc int -> kod bledu wartosc 0 kodu bledu oznacza brak bledu
    //mozna rowniez korzystac z makr EXIT_SUCCESS i EXIT_FAILURE z naglowka cstdlib
}
